#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>

#define SIG_TEST 44 /* we define our own signal, hard coded since SIGRTMIN is different in user and in kernel space */ 

static int isClicked = 0;
static pthread_t clickThread;

void button_click()
{
	printf("test\n");
	system("/home/daniel/.robot/roboLaunch.sh");
	isClicked = 0;
}

void double_click()
{
	system("echo 0 > /sys/devices/msc0/motor0/value");
	system("echo 0 > /sys/devices/msc0/motor1/value");
	system("echo -1 > /sys/devices/msc0/servo0/value");
	system("echo 0 > /sys/devices/msc0/buzzer0/value");
	system("pkill roboLaunch.sh 2 > /dev/null");
	isClicked = 0;
}

struct timer_struct {
	int durration;
	void (*handler)();
};

static void* g_start_timer(void *t)
{
	struct timer_struct *ts = (struct timer_struct*)t;

	usleep(1000 * ts->durration);
	ts->handler();
	free(t);
	pthread_exit(0);
}

pthread_t after_ms_do(int durration, void (*handler)())
{
	pthread_t ret;
	struct timer_struct *t = malloc(sizeof(struct timer_struct));
	t->durration = durration;
	t->handler = handler;
	if(pthread_create(&ret, 0, &g_start_timer,(void*)t))
		return -1;
	return ret;
}

void button_event()
{
	isClicked++;
	if (isClicked == 2) {
		clickThread = after_ms_do(250, &button_click);
	}
	else if (isClicked == 4){
		pthread_cancel(clickThread);
		double_click();
		isClicked = 0;
	}
}

void receiveData(int n, siginfo_t *info, void *unused) {
	button_event();
}

int main ( int argc, char **argv )
{
	int configfd;
	char buf[10];
	/* setup the signal handler for SIG_TEST 
 	 * SA_SIGINFO -> we want the signal handler function with 3 arguments
 	 */
	struct sigaction sig;
	sig.sa_sigaction = receiveData;
	sig.sa_flags = SA_SIGINFO;
	sigaction(SIG_TEST, &sig, NULL);

	/* kernel needs to know our pid to be able to send us a signal ->
 	 * we use debugfs for this -> do not forget to mount the debugfs!
 	 */
	configfd = open("/sys/devices/msc0/button0/pid", O_WRONLY);
	if(configfd < 0) {
		perror("open");
		return -1;
	}
	sprintf(buf, "%i", getpid());
	if (write(configfd, buf, strlen(buf) + 1) < 0) {
		perror("fwrite"); 
		return -1;
	}

        while(1);
	
	return 0;
}
